/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.andersen.web.service;

import com.andersen.database.dao.UserDao;
import com.andersen.database.entity.Roles;
import com.andersen.database.entity.UserEntity;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

/**
 *
 * @author Corvus 11
 */
@Service
public class CustomUserDetailsService implements UserDetailsService {

	private static final Logger LOG = Logger.getLogger(CustomUserDetailsService.class);
        
        public static final int SORT_BY_SNP = 0;
        public static final int SORT_BY_LOGIN = 2;
        public static final int SORT_DIRECTION_ASC = 0;
        public static final int SORT_DIRECTION_DESC = 1;
     
        @Autowired
	private UserDao dao;
        
	@Override
	public UserDetails loadUserByUsername(String username)
			throws UsernameNotFoundException {
		
		LOG.info("Loading users by username " + username);
		
		UserDetails udet = null;
		
		try {
		
		UserEntity dbUser = dao.getUser(username);
		
		if (dbUser == null) {
			LOG.error("Loading of login " + username + " failed.");
			throw new UsernameNotFoundException("Error in loading login from database");
		}
		
		LOG.info("Login " + username + " loaded");
		
                dbUser.setRoles(dao.getUserRoles(dbUser.getId()));
                
		udet = new User(dbUser.getLogin(),
						dbUser.getPassword().toLowerCase(),
						dbUser.isActive(),
						true,
						true,
						true,
						resolveAuthorities(dbUser.getRoles()));
		
		} catch (Exception exc) {
			LOG.error("error in loading users", exc);
		}
		
		return udet;
	}
	
	private Collection<GrantedAuthority> resolveAuthorities(List<String> roles) {
		ArrayList<GrantedAuthority> result = new ArrayList<GrantedAuthority>();
		
                for(String roleName : roles) {
                    LOG.info("Role " + roleName + " found.");
                    result.add(new SimpleGrantedAuthority(roleName));
                }
				
		return result;
	}
        
        public long insertUser(UserEntity user) {
            return dao.insert(user);
        }
        
        public boolean isLoginFree(String login) {
            return dao.getUser(login) == null;
        }
        
        public UserEntity getUser(String login) {
            UserEntity user = dao.getUser(login);
            if (user != null) user.setRoles(dao.getUserRoles(user.getId()));
            return user;
        }
        
        public UserEntity getUser(long id) {
            UserEntity user = dao.getUser(id);
            if (user != null) user.setRoles(dao.getUserRoles(id));
            return user;
        }
        
        public UserEntity getUserByEmployeeId(long id) {
            UserEntity user = dao.getUserByEmployeeId(id);
            if (user != null) user.setRoles(dao.getUserRoles(user.getId()));
            return user;
        }

        public boolean updateUser(UserEntity user) {
            return dao.update(user);
        }
        
        public ArrayList<UserEntity> getUserList() {
            ArrayList<UserEntity> users = dao.getAllObjects();
            for(int i=0;i<users.size();) {
                if (dao.getUserRoles(users.get(i).getId()).contains(Roles.ADMIN))
                    users.remove(i);
                else i++;
            }
            return users;
        }
        
        public ArrayList<UserEntity> queryUsers(int from_item, int count, int sort_by, int sort_order) {
            ArrayList<UserEntity> users = dao.queryUsers(from_item, count, sort_by, sort_order);
            for(int i=0;i<users.size();) {
                List<String> roles = dao.getUserRoles(users.get(i).getId());
                if (roles.contains(Roles.ADMIN))
                    users.remove(i);
                else { 
                    users.get(i).setRoles(roles);
                    i++;
                }
            }
            return users;
        }
        
        public boolean addRole(long userId, String role) {
            return dao.addRole(userId, role);
        }
        
        public boolean dropRole(long userId, String role) {
            return dao.dropRole(userId, role);
        }
        
        public boolean setUserActivity(long userId, boolean active) {
            return dao.setUserActivity(userId,active);
        }
        
        public long getUserCount() {
            return dao.getUserCount();
        }
}
